<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h2>一、用途</h2>
  <div>在日常开发中，我们经常需要判断目标元素是否在视窗之内或者和视窗的距离小于一个值（例如 100 px），从而实现一些常用的功能，例如：</div>
  <ul>
    <li>图片的懒加载</li>
    <li>列表的无限滚动</li>
    <li>计算广告元素的曝光情况</li>
    <li>可点击链接的预加载</li>
  </ul>
  <h2 id="id">二、实现方式</h2>
  <div>判断一个元素是否在可视区域，我们常用的有三种办法：</div>
  <ul>
    <li>offsetTop、scrollTop</li>
    <li>getBoundingClientRect</li>
    <li>Intersection Observer</li>
  </ul>
  <h4>offsetTop、scrollTop</h4>
  <div>offsetTop，元素的上外边框至包含元素的上内边框之间的像素距离</div>
  <br>
  <div>最后，关于scroll系列的属性如下：</div>
  <ul class="target">
    <li>scrollWidth 和 scrollHeight 主要用于确定元素内容的实际大小</li>
    <li>scrollLeft 和 scrollTop 属性既可以确定元素当前滚动的状态，也可以设置元素的滚动位置</li>
    <li>垂直滚动 scrollTop > 0</li>
    <li>水平滚动 scrollLeft > 0</li>
    <li>将元素的 scrollLeft 和 scrollTop 设置为 0，可以重置元素的滚动位置</li>
    <li>上述属性都是只读的，每次访问都要重新开始</li>
  </ul>
  <script>
    console.log(document.getElementById('id').scrollHeight);
    // el.offsetTop - document.documentElement.scrollTop <= viewPortHeight
    function isInViewPortOfOne (el) {
        // viewPortHeight 兼容所有浏览器写法
        const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 
        console.log(viewPortHeight);
        const offsetTop = el.offsetTop
        console.log(offsetTop);
        const scrollTop = document.documentElement.scrollTop
        console.log(scrollTop);
        const top = offsetTop - scrollTop
        console.log(top);
        return top <= viewPortHeight
    }
    isInViewPortOfOne(document.getElementById('id'))

  </script>
  <h4>getBoundingClientRect</h4>
  <div>返回值是一个 DOMRect对象，拥有left, top, right, bottom, x, y, width, 和 height属性</div>
  <script>
    const target = document.querySelector('.target');
    const clientRect = targeisInViewPortt.getBoundingClientRect();
    console.log(clientRect);

    // {
    //   bottom: 556.21875,
    //   height: 393.59375,
    //   left: 333,
    //   right: 1017,
    //   top: 162.625,
    //   width: 684
    // }

    function isInViewPort(element) {
      const viewWidth = window.innerWidth || document.documentElement.clientWidth;
      const viewHeight = window.innerHeight || document.documentElement.clientHeight;
      const {
        top,
        right,
        bottom,
        left,
      } = element.getBoundingClientRect();

      return (
        top >= 0 &&
        left >= 0 &&
        right <= viewWidth &&
        bottom <= viewHeight
      );
    }
  </script>
  <div>
    <h4>Intersection Observer</h4>
    <div>Intersection Observer 即重叠观察者，从这个命名就可以看出它用于判断两个元素是否重叠，因为不用进行事件的监听，性能方面相比getBoundingClientRect会好很多</div>
    <h2>三、案例分析</h2>
    <div>实现：创建了一个十万个节点的长列表，当节点滚入到视窗中时，背景就会从红色变为黄色</div>
  </div>
</body>
</html>